﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Text;
using System.Threading.Tasks;

using RexToy;
using RexToy.UI.WinForm.Controls;
using RexToy.UI.WinForm.Pmlx;

using MGAS.Model;
using MGAS.Model.Entity;

namespace MGAS.UI.View
{
    public class FrmMain : Form
    {
        [PmlxBoundControl("fSwitcher")]
        protected MGAS.UI.Controls.FloorSwitcher _sw;

        [PmlxBoundControl("pAlarm")]
        protected MGAS.UI.Controls.AlarmPanel _pl;

        [PmlxBoundControl("stMain")]
        protected RexToy.UI.WinForm.Controls.StatusBar _status;
        protected RexToy.UI.WinForm.Controls.StatusLabel _stlMain;

        [PmlxBoundControl("btnReset")]
        protected RexToy.UI.WinForm.Controls.Button _btnReset;

        private ConcurrentDictionary<byte, PressureStatus> _statusList;
        private TaskScheduler _uiScheduler;
        private EventHandler<EventArgs> _progressHandler;
        private EventHandler<EventArgs> _doneHandler;

        public FrmMain()
        {
            _statusList = new ConcurrentDictionary<byte, PressureStatus>();
            _btnReset.Click += new EventHandler(_btnReset_Click);
            _sw.FloorSwitched += new EventHandler<UI.Controls.FloorSwitchEventArgs>(_sw_FloorSwitched);
            _pl.FloorStatusChanged += new EventHandler<UI.Controls.FloorStatusChangedEventArgs>(_pl_FloorStatusChanged);
            _pl.BackButtonClicked += new EventHandler<EventArgs>(_pl_BackButtonClicked);

            _stlMain = (RexToy.UI.WinForm.Controls.StatusLabel)_status.Items["stlMain"];
            _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

            _progressHandler = new EventHandler<EventArgs>(meta_collector_PollingProgress);
            _doneHandler = new EventHandler<EventArgs>(meta_collector_PollingMetaDone);
        }

        void _btnReset_Click(object sender, EventArgs e)
        {
            _btnReset.Enabled = false;
            var collector = Program.Context.Lookup<ISensorDataCollector>();
            collector.StopCollect();

            var meta_collector = Program.Context.Lookup<ISensorMetaDataCollector>();

            meta_collector.PollingProgress += _progressHandler;
            meta_collector.PollingMetaDone += _doneHandler;
            meta_collector.StartPollingMeta();
        }

        void meta_collector_PollingMetaDone(object sender, EventArgs e)
        {
            var meta_collector = Program.Context.Lookup<ISensorMetaDataCollector>();
            AllocMapWriter.ReWrite(meta_collector.GetMetaInfos());

            meta_collector.PollingProgress -= _progressHandler;
            meta_collector.PollingMetaDone -= _doneHandler;

            AllocMap.Destroy();
            Program.Restart = true;
            var collector = Program.Context.Lookup<ISensorDataCollector>();
            collector.StartCollect();
            Task t = new Task(() =>
                {
                    this.Close();
                });
            t.Start(_uiScheduler);
        }

        void meta_collector_PollingProgress(object sender, EventArgs e)
        {
            var meta_collector = Program.Context.Lookup<ISensorMetaDataCollector>();

            Task t = new Task(() =>
                {
                    var p = (float)meta_collector.Progress / (float)256 * 100;
                    _stlMain.Text = string.Format("{0}%完成", p.ToString("F2"));
                });
            t.Start(_uiScheduler);
        }

        void _pl_BackButtonClicked(object sender, EventArgs e)
        {
            _pl.Visible = false;
            _sw.Visible = true;
        }

        void _pl_FloorStatusChanged(object sender, Controls.FloorStatusChangedEventArgs e)
        {
            _sw.SetAlarmStatus(e.Location, e.Alarm);
        }

        void _sw_FloorSwitched(object sender, Controls.FloorSwitchEventArgs e)
        {
            _sw.Visible = false;
            _pl.Visible = true;
            _pl.SwitchToLocation(e.Location);
        }

        protected override void OnLoad(EventArgs e)
        {
            var dblock = Program.Context.Lookup<ISensorDataBlock>();
            _pl.SetDataSource(dblock);

            dblock.SensorDataChanged += new EventHandler<SensorDataChangedEventArgs>(dblock_SensorDataChanged);
        }

        void dblock_SensorDataChanged(object sender, SensorDataChangedEventArgs e)
        {
            var dblock = Program.Context.Lookup<ISensorDataBlock>();

            var data = dblock.GetData(e.Id);
            if (data == null)
            {
                return;
            }
            _statusList[e.Id] = data.Status;

            Task t = new Task(() =>
                {
                    UpdateSummary(dblock);
                });
            t.Start(_uiScheduler);
        }

        //Refactor:Text
        private void UpdateSummary(ISensorDataBlock dblock)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var kvp in _statusList)
            {
                if (kvp.Value != PressureStatus.Normal)
                {
                    var data = dblock.GetData(kvp.Key);
                    if (data == null)
                    {
                        continue;
                    }
                    var loc = AllocMap.Instance().FindLocationBySensor(kvp.Key);
                    var b = AllocMap.Instance().FindBuildingByLocation(loc);

                    sb.AppendFormat("{0}{1}{2}-[{3}] / ", b.Text, loc.Text, AllocMap.Instance().FindSensorMeta(kvp.Key).Text, EnumEx.GetDescription(data.Status));
                }
            }
            sb.RemoveEnd(" / ");
            if (sb.Length > 0)
                _stlMain.Text = sb.ToString();
            else
                _stlMain.Text = "系统运行正常";
        }
    }
}
